''' 
Copyright (c) 2006-2007, PreFab Software Inc.

Copyright (c) 2006, Andrew Gwozdziewycz <apgwoz@gmail.com>
All rights reserved.

aaloy: Modied search engine. Escape search pattern.
       7-09-2008: added a new search engine. See searcher documentation
'''


import calendar, datetime, time

from django.contrib.auth.models import User
from django.contrib.contenttypes.models import ContentType
from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import get_object_or_404
from django.http import Http404
from django.template import RequestContext, loader
from django.views.generic.date_based import archive_day
from django.utils.safestring import mark_safe
from blogmaker.blog.models import Tag, Entry
import blogmaker.comments.views
from django.utils.encoding import smart_unicode
from django.views.decorators.cache import cache_control
from django.template.defaultfilters import iriencode
import re
import time
from blogforms import SearchForm 

def __slugify(value):    
    """
    Normalizes string, converts to lowercase, removes non-alpha characters,
    and converts spaces to hyphens.
    """
    "Copied and pasted from Django slugify filter"
    import unicodedata
    value = unicodedata.normalize('NFKD', value).encode('ascii', 'ignore')
    value = unicode(re.sub('[^\w\s-]', '', value).strip().lower())
    return mark_safe(re.sub('[-\s]+', '-', value))

@cache_control(must_revalidate=True, max_age=7200)
def view_tagged_items(request, tag):
    ''' View all blog entries for a given tag '''
    #current_tag = get_object_or_404(Tag, tag=tag)
    tags = Tag.objects.all()
    for db_tag in tags:
        slug_field = __slugify(db_tag.tag)
        if slug_field==tag:
            current_tag = db_tag
            break
    else:
        raise Http404, "No tag match"
    entries = current_tag.entry_set.current_active().select_related()
    
    t = loader.get_template('blog/tag_index.html')
    c = RequestContext(request, {'object_list': entries, 'tag': tag})
    return HttpResponse(t.render(c))

@cache_control(must_revalidate=True, max_age=3600)
def view_tags(request):
    ''' View two lists of tags, one by popularity, one alphabetical '''
    
    entries = Entry.objects.current_active()
    all_tags = Tag.objects.all()
    popular_tags = []
    alpha_tags = []
    total_tags = 0
    for tag in all_tags:
        entry_count = entries.filter(tags__exact=tag).count()
        total_tags = total_tags + entry_count
        if entry_count > 0:
            tag = str(tag)
            popular_tags.append( (entry_count, tag) )
            popular_tags.sort(reverse=True)
            alpha_tags.append( (tag, entry_count) )
            alpha_tags.sort(key=lambda x: x[0].lower())
    keys = "|".join(iriencode(x[0]) for x in alpha_tags)
    values =",".join([str(x[1]*100.0/total_tags) for x in alpha_tags])
            
    t = loader.get_template('blog/tag_list.html')
    c = RequestContext(request, {'alpha_list': alpha_tags, 'popular_list': popular_tags, 'taglist': all_tags, 'keys':keys,"values":values})
    return HttpResponse(t.render(c))

@cache_control(must_revalidate=True, max_age=3600)
def view_user_items(request, user):
    ''' View all items by a specific user '''
    
    user = get_object_or_404(User, username=user)
    entries = Entry.objects.current_active().filter(user__exact=user)
    
    t = loader.get_template('blog/user_index.html')
    c = RequestContext(request, {'object_list': entries, 'postedby': user, 'userposts': entries})
    return HttpResponse(t.render(c))

    
def search(request):
    ''' Search entries for term (in body and headline). Modified to use Django-xapian '''
    t = 'blog/search.html' #Default template
    search = 'Search'
    search_terms = ''
    found_entries = None
    searched = dict()
    start_time = time.time()
    if not request.POST:
        form = SearchForm()
    else:
        form = SearchForm(request.POST)
        start_time = time.time()
        search = smart_unicode(request.POST['query'])
        if form.is_valid():
            # build the searcher engine
            search_terms = form.cleaned_data['query']
            found_entries = Entry.indexer.search(search_terms)
            request.session['search_error']=''
            t = 'blog/search_results.html'
        else:
            request.session['search_error'] = 'Cerca no valida'
            return HttpResponseRedirect('/')
    template = loader.get_template(t)

    c = RequestContext(request, {'form':form, 'object_list':found_entries, 'query': search_terms, 'search': search, 'time': time.time()-start_time})
    return HttpResponse(template.render(c))


@cache_control(must_revalidate=True, max_age=3600)
def extras_day(request, year, month, day, queryset, date_field,
        month_format='%m', day_format='%d'):
    ''' Add a list of days and if and type of entries contained,
    then send to generic archive_day view '''
    number = calendar.mdays[datetime.date(*time.strptime(year+month+day, '%Y'+month_format+day_format)[:3]).month]
    days = range(1,number+1,1)
    day_values = []
    for d in days:
        current_day = int(day)
        day_posts = Entry.objects.current_active().filter(pub_date__day=int(d), pub_date__month=int(month), pub_date__year=int(year))   
        if not day_posts:
            value = 'no'
        elif d == current_day:
            value = 'current'
        else:
            value = 'yes'
        day_values.append(value)
    extras = {'days': day_values}
    return archive_day(request, year, month, day, queryset, date_field,
        month_format='%m', day_format='%d', extra_context = extras)

@cache_control(must_revalidate=True, max_age=3600)
def trackback(request, slug):
    ''' This is the view that receives external trackback requests '''
    blog = get_object_or_404(Entry, slug=slug)
    content_type = ContentType.objects.get(app_label__exact='blog', model__exact='entry')
    return blogmaker.comments.views.trackback(request, content_type.id, blog.id, blog.get_absolute_url())

def table(request):
    t = 'blog/table.html' #Default template  
    template = loader.get_template(t)
    c = RequestContext(request,{})    
    return HttpResponse(template.render(c))  
